package common.servlet;

import java.io.File;
import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;
import javax.ws.rs.core.Cookie;

import msg.MessageManager;
import msg.visitors.MessageToJson;

import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.Tomcat;
import org.apache.wink.client.ClientConfig;
import org.apache.wink.client.ClientResponse;
import org.apache.wink.client.RestClient;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;

import registration.RegistrationManager;
import user.LoginManager;
import user.servlet.UsersResource;

import com.sun.jersey.spi.container.servlet.ServletContainer;
import common.DALTests;

@SuppressWarnings({"javadoc", "static-method"})
public abstract class ServletTests extends DALTests {
	private static int						port			= 14928;
	private static final String				SERVLET_NAME	= "testServlet";
	private static final String				PATH			= "/test";
	private static Tomcat					tc;

	protected static RestClient				rc;
	protected static final MessageToJson	jsoner			= new MessageToJson();

	@BeforeClass
	public static void setupBeforeClass() throws Exception {
		port++;
		DALTests.setupBeforeClass();
		setupTomcat();
		setupRestClient();
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		DALTests.tearDownAfterClass();
		tc.stop();
	}

	@Before
	public void setupServlets() throws Exception {
		RegistrationManager.getNewInstance(t).clear();
		MessageManager.getNewInstance(t).clear();
		LoginManager.getNewInstance(t).clear();
		// committing here so the resources won't be blocked
		t.commit();
	}

	@Override
	public void tearDown() throws Exception {
		// do nothing
		// overridden so no commits will be performed
	}

	private static void setupRestClient() {
		Application app = new Application() {
			@Override
			public java.util.Set<java.lang.Class<?>> getClasses() {
				Set<Class<?>> classes = new HashSet<>();
				classes.add(JSONArrayBodyReaderWriter.class);
				classes.add(JSONBodyReaderWriter.class);
				classes.add(BooleanBodyReaderWriter.class);
				return classes;
			}
		};

		ClientConfig cfg = new ClientConfig();
		cfg.applications(app);
		rc = new RestClient(cfg);
	}

	private static void setupTomcat() throws Exception {
		tc = new Tomcat();
		tc.setPort(port);
		Context ctx = tc.addContext("/", new File(".").getAbsolutePath());
		ServletContainer sc = new ServletContainer();
		Wrapper w = Tomcat.addServlet(ctx, SERVLET_NAME, sc);
		w.addInitParameter("com.sun.jersey.config.property.packages",
				"user.servlet; common.servlet; msg.servlet; registration.servlet");
		ctx.addServletMapping(PATH + "/*", SERVLET_NAME);
		tc.start();
	}

	/**
	 * @return the rESOURCES
	 */
	protected static String getResources() {
		return "http://localhost:" + port + PATH + "/";
	}

	protected static String getId(ClientResponse cr) {
		String[] path = cr.getHeaders().getFirst("Location").split("/");
		return path[path.length - 1];
	}

	protected static Cookie createCookie(Object value) {
		return new Cookie(UsersResource.COOKIE_NAME, value.toString());
	}
}
